#include "OpenGLWidgetMultiObject.h"
#include<QDebug>
// EBO 测试


static unsigned int VBOs[2], VAOs[2];
static unsigned int shaderProgram;
static unsigned int shaderProgram2;
//static unsigned int EBO;

static float firstTriangle[] = {
-0.9f, -0.5f, 0.0f,  // left 
0.0f,-0.5f, 0.0f, //  right
-0.45f, 0.5f, 0.0f//  top
};

static float secondTriangle[] = {
	-0.0f, -0.5f, 0.0f,  // left
	0.9f,-0.5f, 0.0f, // right
	0.45f, 0.5f, 0.0f, // top
};

static const char* vertexShaderSource = R"(
#version 330 core
layout(location=0) in vec3 aPos;
void main()
{
	gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
)";

static const char* fragmentShaderSource = R"(
out vec4 FragColor;
void main()
{
	FragColor = vec4(1.0f, 0.5f, 0.3f, 1.0f);
}
)"; // 橘色

static const char* fragmentShaderSource2 = R"(
out vec4 FragColor;
void main()
{
	FragColor = vec4(1.0f, 1.0f, 0.0f, 1.0f);
}
)"; // 黄色

OpenGLWidgetMultiObject::OpenGLWidgetMultiObject(QWidget* parent):QOpenGLWidget( parent)
{

}

OpenGLWidgetMultiObject::~OpenGLWidgetMultiObject()
{
	makeCurrent();
	glDeleteVertexArrays(2, VAOs);
	glDeleteBuffers(2, VAOs);
	glDeleteProgram(shaderProgram);
	glDeleteProgram(shaderProgram2);
	doneCurrent();
}

void OpenGLWidgetMultiObject::initializeGL()
{
	initializeOpenGLFunctions(); // 初始化opengl 相关的函数
	// 创建vao vbo 对象 ，并赋予ID
	glGenVertexArrays(2, VAOs);
	glGenBuffers(2, VBOs);

	// 绑定VBO VAO 对象 0 =============
	glBindVertexArray(VAOs[0]);
	glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);

	// 为当前绑定到target 的缓冲区对象创建一个新的数据存储。
	// 如果data 不是NULL，则使用来自此指针的数据初始化数据存储
	glBufferData(GL_ARRAY_BUFFER, sizeof(firstTriangle), firstTriangle, GL_STATIC_DRAW);
	// 告知显卡如何解析缓冲区里的属性值
	glVertexAttribPointer(0 ,3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),(void*)0);

	// 开启VAO 管理的第一个属性值
	glEnableVertexAttribArray(0);
	/*glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);*/


	// 绑定VBO VAO 对象 1 ==============
	glBindVertexArray(VAOs[1]);
	glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);

	// 为当前绑定到target 的缓冲区对象创建一个新的数据存储。
	// 如果data 不是NULL，则使用来自此指针的数据初始化数据存储
	glBufferData(GL_ARRAY_BUFFER, sizeof(secondTriangle), secondTriangle, GL_STATIC_DRAW);
	// 告知显卡如何解析缓冲区里的属性值
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

	// 开启VAO 管理的第一个属性值
	glEnableVertexAttribArray(0);
	 

	// build and compile our shader program
	// 顶点着色器
	unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
	glCompileShader(vertexShader);

	//check for shader compile errors
	int success; char infoLog[512];
	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
		qDebug() << "error::shader::vertex::compileation_failed  " << infoLog;
	}
	// 片段着色器
	unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
	glCompileShader(fragmentShader);
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
		qDebug() << "error::shader::fragment::compileation_failed " << infoLog;
	}

	// 片段着色器2
	unsigned int fragmentShader2 = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader2, 1, &fragmentShaderSource2, NULL);
	glCompileShader(fragmentShader2);
	glGetShaderiv(fragmentShader2, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(fragmentShader2, 512, NULL, infoLog);
		qDebug() << "error::shader::fragment::compileation_failed 2 " << infoLog;
	}

	// link shaders
	shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram, vertexShader);
	glAttachShader(shaderProgram, fragmentShader);
	glLinkProgram(shaderProgram);
	// check for linking errors
	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
	if (!success)
	{
		glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
		qDebug() << "error::shader::programe::linking_failed " << infoLog;
	}

	// link shaders 2
	shaderProgram2 = glCreateProgram();
	glAttachShader(shaderProgram2, vertexShader);
	glAttachShader(shaderProgram2, fragmentShader2);
	glLinkProgram(shaderProgram2);
	// check for linking errors
	glGetProgramiv(shaderProgram2, GL_LINK_STATUS, &success);
	if (!success)
	{
		glGetProgramInfoLog(shaderProgram2, 512, NULL, infoLog);
		qDebug() << "error::shader::programe::linking_failed 2 " << infoLog;
	}


	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);
	glDeleteShader(fragmentShader2);
}

void OpenGLWidgetMultiObject::resizeGL(int w, int h)
{
}

void OpenGLWidgetMultiObject::paintGL()
{
	glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	qDebug() << "paintGL";

	glUseProgram(shaderProgram);
	glBindVertexArray(VAOs[0]);
	glDrawArrays(GL_TRIANGLES,0,3);

	glUseProgram(shaderProgram2);
	glBindVertexArray(VAOs[1]);
	glDrawArrays(GL_TRIANGLES, 0, 3);
}
